package com.example.service.impl;

import com.example.common.Result;
import com.example.common.PageResult;
import com.example.entity.*;
import com.example.exception.ForeignKeyException;
import com.example.mapper.*;
import com.example.service.AdminService;
import com.example.service.MenuPermissionMappingService;
import com.example.service.PermissionDependencyService;
import com.example.service.PermissionSyncService;
import com.example.util.PasswordUtil;
import com.example.util.JwtUserUtil;
import com.example.dto.RechargeRecordQueryDTO;
import com.example.vo.MenuVO;
import com.example.vo.UserWithRoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AdminServiceImpl implements AdminService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private MenuMapper menuMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    
    @Autowired
    private PasswordUtil passwordUtil;

    @Autowired
    private PermissionDependencyService permissionDependencyService;

    @Autowired
    private MenuPermissionMappingService menuPermissionMappingService;

    @Autowired
    private PermissionSyncService permissionSyncService;
    
    @Autowired
    private UserBalanceMapper userBalanceMapper;
    
    @Autowired
    private RechargeRecordMapper rechargeRecordMapper;
    
    @Autowired
    private JwtUserUtil jwtUserUtil;
    
    @Override
    public Result<List<UserWithRoleVO>> getAllUsers() {
        try {
            List<User> users = userMapper.selectByStatus(1);
            
            List<UserWithRoleVO> userWithRoleVOs = users.stream().map(user -> {
                UserWithRoleVO userVO = new UserWithRoleVO();
                userVO.setId(user.getId());
                userVO.setUsername(user.getUsername());
                userVO.setNickname(user.getNickname());
                userVO.setEmail(user.getEmail());
                userVO.setPhone(user.getPhone());
                userVO.setStatus(user.getStatus());
                userVO.setCreateTime(user.getCreateTime());
                userVO.setUpdateTime(user.getUpdateTime());
                
                // 获取用户角色信息
                List<UserRole> userRoles = userRoleMapper.selectByUserId(user.getId());
                
                List<String> roleNames = new ArrayList<>();
                List<Long> roleIds = new ArrayList<>();
                
                for (UserRole userRole : userRoles) {
                    Role role = roleMapper.selectById(userRole.getRoleId());
                    if (role != null) {
                        roleNames.add(role.getRoleName());
                        roleIds.add(role.getId());
                    }
                }
                
                userVO.setRoleNames(roleNames);
                userVO.setRoleIds(roleIds);
                
                return userVO;
            }).collect(Collectors.toList());
            
            return Result.success(userWithRoleVOs);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<UserWithRoleVO>> getUsersByRole(Long roleId) {
        try {
            // 根据角色ID获取用户角色关联
            List<UserRole> userRoles = userRoleMapper.selectByRoleId(roleId);
            
            List<UserWithRoleVO> userWithRoleVOs = new ArrayList<>();
            
            for (UserRole userRole : userRoles) {
                User user = userMapper.selectById(userRole.getUserId());
                if (user != null && user.getStatus() == 1) { // 只返回启用的用户
                    UserWithRoleVO userVO = new UserWithRoleVO();
                    userVO.setId(user.getId());
                    userVO.setUsername(user.getUsername());
                    userVO.setNickname(user.getNickname());
                    userVO.setEmail(user.getEmail());
                    userVO.setPhone(user.getPhone());
                    userVO.setStatus(user.getStatus());
                    userVO.setCreateTime(user.getCreateTime());
                    userVO.setUpdateTime(user.getUpdateTime());
                    
                    // 获取用户所有角色信息
                    List<UserRole> allUserRoles = userRoleMapper.selectByUserId(user.getId());
                    
                    List<String> roleNames = new ArrayList<>();
                    List<Long> roleIds = new ArrayList<>();
                    
                    for (UserRole ur : allUserRoles) {
                        Role role = roleMapper.selectById(ur.getRoleId());
                        if (role != null) {
                            roleNames.add(role.getRoleName());
                            roleIds.add(role.getId());
                        }
                    }
                    
                    userVO.setRoleNames(roleNames);
                    userVO.setRoleIds(roleIds);
                    
                    userWithRoleVOs.add(userVO);
                }
            }
            
            return Result.success(userWithRoleVOs);
        } catch (Exception e) {
            return Result.error("根据角色获取用户列表失败：" + e.getMessage());
        }
    }
    
    @Override
    public Result<Void> addUser(User user) {
        try {
            // 检查用户名是否已存在
            User existUser = userMapper.selectByUsername(user.getUsername());
            if (existUser != null) {
                return Result.error("用户名已存在");
            }
            
            // 密码加密
            user.setPassword(passwordUtil.encode(user.getPassword()));
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setStatus(1);
            user.setDeleted(0);
            
            userMapper.insert(user);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> updateUser(Long id, User user) {
        try {
            // 检查用户是否存在
            User existUser = userMapper.selectById(id);
            if (existUser == null) {
                return Result.error("用户不存在");
            }
            
            // 检查用户名是否被其他用户使用
            User duplicateUser = userMapper.selectByUsernameExcludeId(user.getUsername(), id);
            if (duplicateUser != null) {
                return Result.error("用户名已被其他用户使用");
            }
            
            // 更新用户信息
            user.setId(id);
            user.setUpdateTime(LocalDateTime.now());
            
            // 如果密码不为空，则更新密码
            if (user.getPassword() != null && !user.getPassword().trim().isEmpty()) {
                user.setPassword(passwordUtil.encode(user.getPassword()));
            } else {
                // 保持原密码
                user.setPassword(existUser.getPassword());
            }
            
            userMapper.updateById(user);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> deleteUser(Long userId) {
        try {
            // 检查是否为当前登录用户
            Long currentUserId = jwtUserUtil.getCurrentUserIdFromContext();
            if (currentUserId != null && currentUserId.equals(userId)) {
                return Result.error("不能删除当前登录的用户");
            }

            // 检查外键约束
            List<String> conflicts = new ArrayList<>();
            
            // 检查用户余额记录
            UserBalance userBalance = userBalanceMapper.selectByUserId(userId);
            if (userBalance != null) {
                // 检查余额是否为0
                if (userBalance.getBalance() != null && userBalance.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                    conflicts.add("用户账户余额为 " + userBalance.getBalance() + " 元，需要先清空余额");
                }
                
                // 检查累计充值记录
                if (userBalance.getTotalRecharge() != null && userBalance.getTotalRecharge().compareTo(BigDecimal.ZERO) > 0) {
                    conflicts.add("用户有累计充值记录 " + userBalance.getTotalRecharge() + " 元");
                }
            }
            
            // 检查充值记录
            RechargeRecordQueryDTO queryDTO = new RechargeRecordQueryDTO();
            queryDTO.setUserId(userId);
            long rechargeCount = rechargeRecordMapper.selectCountByQuery(queryDTO);
            if (rechargeCount > 0) {
                conflicts.add("用户有 " + rechargeCount + " 条充值记录");
            }
            
            // 检查用户角色关联
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            if (!userRoles.isEmpty()) {
                conflicts.add("用户被分配了 " + userRoles.size() + " 个角色");
            }
            
            // 如果存在冲突，抛出外键约束异常
            if (!conflicts.isEmpty()) {
                // 转换为RelatedData列表
                List<ForeignKeyException.RelatedData> relatedDataList = new ArrayList<>();
                for (String conflict : conflicts) {
                    relatedDataList.add(new ForeignKeyException.RelatedData("constraint", "数据约束", conflict));
                }
                throw ForeignKeyException.userConstraintViolation("用户", relatedDataList);
            }
            
            // 软删除：设置状态为0，删除标记为1
            User existUser = userMapper.selectById(userId);
            if (existUser == null) {
                return Result.error("用户不存在");
            }
            
            // 确保软删除设置正确
            existUser.setStatus(0);        // 禁用状态
            existUser.setDeleted(1);       // 删除标记
            existUser.setUpdateTime(LocalDateTime.now());
            
            // 执行更新
            int updateResult = userMapper.updateById(existUser);
            if (updateResult <= 0) {
                return Result.error("删除用户失败");
            }
            
            // 删除用户角色关联
            userRoleMapper.deleteByUserId(userId);
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<User> getUserById(Long id) {
        try {
            User user = userMapper.selectById(id);
            if (user == null) {
                return Result.error("用户不存在");
            }

            // 清空密码字段
            user.setPassword(null);
            return Result.success(user);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<List<User>> searchUsers(String keyword, int limit) {
        try {
            if (keyword == null || keyword.trim().isEmpty()) {
                return Result.success(List.of());
            }

            // 普通用户角色ID为2，只搜索具有普通用户角色的用户
            Long userRoleId = 2L;
            List<User> users = userMapper.selectUsersByRoleWithPagination(userRoleId, 0, limit, keyword.trim());

            // 清空密码字段
            users.forEach(user -> user.setPassword(null));

            return Result.success(users);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<PageResult<User>> searchUsersWithPagination(String keyword, int page, int size) {
        try {
            int offset = (page - 1) * size;

            // 获取具有"普通用户"角色的用户列表
            List<User> users;
            long total;

            // 普通用户角色ID为2
            Long userRoleId = 2L;

            if (keyword == null || keyword.trim().isEmpty()) {
                // 如果没有关键词，获取所有具有普通用户角色的启用用户
                users = userMapper.selectUsersByRoleWithPagination(userRoleId, offset, size, null);
                total = userMapper.selectUserCountByRole(userRoleId, null);
            } else {
                // 有关键词时进行搜索，只在具有普通用户角色的用户中搜索
                users = userMapper.selectUsersByRoleWithPagination(userRoleId, offset, size, keyword.trim());
                total = userMapper.selectUserCountByRole(userRoleId, keyword.trim());
            }

            // 清空密码字段
            users.forEach(user -> user.setPassword(null));

            PageResult<User> pageResult = new PageResult<>();
            pageResult.setRecords(users);
            pageResult.setTotal(total);
            pageResult.setSize(size);
            pageResult.setCurrent(page);

            return Result.success(pageResult);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<Long>> getUserRoles(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            List<Long> roleIds = userRoles.stream()
                    .map(UserRole::getRoleId)
                    .collect(Collectors.toList());
            return Result.success(roleIds);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignRole(Long userId, Long roleId) {
        try {
            // 检查用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 检查角色是否存在
            Role role = roleMapper.selectById(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }
            
            // 获取用户当前的所有角色
            List<UserRole> existUserRoles = userRoleMapper.selectByUserId(userId);
            
            // 检查用户是否已经拥有该角色
            boolean hasRole = existUserRoles.stream().anyMatch(ur -> ur.getRoleId().equals(roleId));
            if (hasRole) {
                return Result.error("用户已拥有该角色");
            }
            
    
            
            // 先删除用户的所有旧角色（软删除）
            if (!existUserRoles.isEmpty()) {
                for (UserRole existUserRole : existUserRoles) {
                    existUserRole.setDeleted(1);
                    userRoleMapper.updateById(existUserRole);
                }
            }
            
            // 分配新角色
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRole.setCreateTime(LocalDateTime.now());
            userRole.setDeleted(0);
            userRoleMapper.insert(userRole);
            
            // 角色分配成功
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    

    
    @Override
    public Result<List<Role>> getAllRoles() {
        try {
            // 获取所有角色（包括启用和禁用的），但排除已删除的
            List<Role> roles = roleMapper.selectList(new Role());
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> addRole(Role role) {
        try {
            // 检查角色名是否已存在
            Role existRole = roleMapper.selectByRoleName(role.getRoleName());
            if (existRole != null) {
                return Result.error("角色名已存在");
            }
            
            // 检查角色代码是否已存在
            Role existRoleCode = roleMapper.selectByRoleCode(role.getRoleCode());
            if (existRoleCode != null) {
                return Result.error("角色代码已存在");
            }
            
            role.setCreateTime(LocalDateTime.now());
            role.setUpdateTime(LocalDateTime.now());
            role.setStatus(1);
            role.setDeleted(0);
            
            roleMapper.insert(role);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> updateRole(Long id, Role role) {
        try {
            // 检查角色是否存在
            Role existRole = roleMapper.selectById(id);
            if (existRole == null) {
                return Result.error("角色不存在");
            }
            
            // 检查角色名是否被其他角色使用
            Role duplicateRoleName = roleMapper.selectByRoleNameExcludeId(role.getRoleName(), id);
            if (duplicateRoleName != null) {
                return Result.error("角色名已被其他角色使用");
            }
            
            // 检查角色代码是否被其他角色使用
            Role duplicateRoleCode = roleMapper.selectByRoleCodeExcludeId(role.getRoleCode(), id);
            if (duplicateRoleCode != null) {
                return Result.error("角色代码已被其他角色使用");
            }
            
            // 更新角色信息
            role.setId(id);
            role.setUpdateTime(LocalDateTime.now());
            
            roleMapper.updateById(role);
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Void> deleteRole(Long id) {
        try {
            // 检查角色是否存在
            Role existRole = roleMapper.selectById(id);
            if (existRole == null) {
                return Result.error("角色不存在");
            }
            
            // 检查是否有用户使用该角色
            List<UserRole> userRoles = userRoleMapper.selectByRoleId(id);
            if (!userRoles.isEmpty()) {
                return Result.error("该角色正在被用户使用，无法删除");
            }
            
            // 软删除：设置状态为0
            existRole.setStatus(0);
            existRole.setUpdateTime(LocalDateTime.now());
            roleMapper.updateById(existRole);
            
            // 删除角色菜单关联
            roleMenuMapper.deleteByRoleId(id);
            
            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<Role> getRoleById(Long id) {
        try {
            Role role = roleMapper.selectById(id);
            if (role == null) {
                return Result.error("角色不存在");
            }
            return Result.success(role);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<MenuVO>> getAllMenus() {
        try {
            // 获取所有启用的菜单和按钮权限
            List<Menu> menus = menuMapper.selectByTypeAndStatus(null, 1);
            List<MenuVO> menuVOs = menus.stream().map(menu -> {
                MenuVO menuVO = new MenuVO();
                menuVO.setId(menu.getId());
                menuVO.setMenuName(menu.getMenuName());
                menuVO.setMenuCode(menu.getMenuCode());
                menuVO.setParentId(menu.getParentId());
                menuVO.setMenuType(menu.getMenuType());
                menuVO.setPath(menu.getPath());
                menuVO.setComponent(menu.getComponent());
                menuVO.setIcon(menu.getIcon());
                menuVO.setSort(menu.getSort());
                return menuVO;
            }).collect(Collectors.toList());
            
            // 构建菜单树
            List<MenuVO> menuTree = buildMenuTree(menuVOs, 0L);
            return Result.success(menuTree);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    public Result<List<Long>> getRoleMenus(Long roleId) {
        try {
            List<RoleMenu> roleMenus = roleMenuMapper.selectByRoleId(roleId);
            List<Long> menuIds = roleMenus.stream()
                    .map(RoleMenu::getMenuId)
                    .collect(Collectors.toList());
            return Result.success(menuIds);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignMenu(Long roleId, List<Long> menuIds) {
        try {
            // 检查角色是否存在
            Role role = roleMapper.selectById(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }

            // 删除原有的角色菜单关联
            roleMenuMapper.deleteByRoleId(roleId);

            // 添加新的角色菜单关联
            if (menuIds != null && !menuIds.isEmpty()) {
                // 解析菜单依赖，自动包含父级菜单
                Set<Long> allMenuIds = permissionDependencyService.resolveMenuDependencies(menuIds);

                // 分配菜单
                for (Long menuId : allMenuIds) {
                    RoleMenu roleMenu = new RoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(menuId);
                    roleMenu.setCreateTime(LocalDateTime.now());
                    roleMenu.setDeleted(0);
                    roleMenuMapper.insert(roleMenu);
                }

                // 使用权限同步服务自动分配菜单对应的权限
                int syncedPermissions = permissionSyncService.syncPermissionsForMenus(roleId, new ArrayList<>(allMenuIds));

                int addedMenuCount = allMenuIds.size() - menuIds.size();
                if (addedMenuCount > 0 || syncedPermissions > 0) {
                    System.out.println("分配菜单成功：");
                    if (addedMenuCount > 0) {
                        System.out.println("  - 已自动包含 " + addedMenuCount + " 个父级菜单");
                    }
                    if (syncedPermissions > 0) {
                        System.out.println("  - 已自动分配 " + syncedPermissions + " 个对应权限");
                    }
                }
            }

            return Result.success();
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    

    
    @Override
    public Result<List<Role>> getUserRoleDetails(Long userId) {
        try {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(userId);
            List<Role> roles = userRoles.stream()
                    .map(userRole -> roleMapper.selectById(userRole.getRoleId()))
                    .filter(role -> role != null)
                    .collect(Collectors.toList());
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error("获取用户角色失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public Result<Void> assignRolesToUser(Long userId, List<Long> roleIds) {
        try {
            // 检查用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 删除原有角色关联
            userRoleMapper.deleteByUserId(userId);
            
            // 添加新的角色关联
            if (roleIds != null && !roleIds.isEmpty()) {
                for (Long roleId : roleIds) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    userRole.setCreateTime(LocalDateTime.now());
                    userRole.setDeleted(0);
                    userRoleMapper.insert(userRole);
                }
            }
            
            return Result.success();
        } catch (Exception e) {
            return Result.error("分配角色失败：" + e.getMessage());
        }
    }

    /**
     * 构建菜单树
     */
    private List<MenuVO> buildMenuTree(List<MenuVO> menus, Long parentId) {
        return menus.stream()
                .filter(menu -> {
                    if (parentId == null) {
                        return menu.getParentId() == null || menu.getParentId() == 0;
                    } else {
                        return parentId.equals(menu.getParentId());
                    }
                })
                .map(menu -> {
                    menu.setChildren(buildMenuTree(menus, menu.getId()));
                    return menu;
                })
                .collect(Collectors.toList());
    }

} 